package com.ant.storage.handler;

import com.ant.storage.common.ResultCode;
import com.ant.storage.common.ResultVo;
import com.fasterxml.jackson.core.JsonParseException;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;


/**
 * @author hzd
 * @version 1.0
 * @date 2022/3/16 14:13
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    /**
     * 处理自定义的业务异常
     * @param request
     * @param e
     * @return
     */
    @ExceptionHandler(value = AntException.class)
    @ResponseBody
    public ResultVo CustomExceptionHandler(HttpServletRequest request, AntException e){
        logger.error("发生业务异常！原因是：{}",e.getErrorMsg());
        return ResultVo.failure(e.getErrorCode(),e.getErrorMsg());
    }

    /**
     * 处理空指针的异常
     * @param request
     * @param e
     * @return
     */
    @ExceptionHandler(value =NullPointerException.class)
    @ResponseBody
    public ResultVo exceptionHandler(HttpServletRequest request, NullPointerException e){
        logger.error("发生空指针异常！原因是:",e);
        return ResultVo.fail(ResultCode.PARAM_IS_BLANK);
    }

//    @ExceptionHandler(value = ConstraintViolationException.class)
//    public Result handle1(ConstraintViolationException ex){
//        StringBuilder msg = new StringBuilder();
//        Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
//        for (ConstraintViolation<?> constraintViolation : constraintViolations) {
//            PathImpl pathImpl = (PathImpl) constraintViolation.getPropertyPath();
//            String paramName = pathImpl.getLeafNode().getName();
//            String message = constraintViolation.getMessage();
//            msg.append("[").append(message).append("]");
//        }
//        logger.error(msg.toString(),ex);
//        // 注意：Response类必须有get和set方法，不然会报错
//        return new Result(ResultCode.PARAM_IS_BLANK);
//    }

//    @ExceptionHandler(MethodArgumentNotValidException.class)
//    public String methodArgumentNotValidException(MethodArgumentNotValidException e) {
//        // 从异常对象中拿到ObjectError对象
//        ObjectError objectError = e.getBindingResult().getAllErrors().get(0);
//        // 然后提取错误提示信息进行返回
//        return objectError.getDefaultMessage();
//    }


    /**
     * 验证参数异常错误
     * @param ex
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public ResultVo handle2(MethodArgumentNotValidException ex){
        BindingResult bindingResult = ex.getBindingResult();
        if(bindingResult!=null){
            if(bindingResult.hasErrors()){
                FieldError fieldError = bindingResult.getFieldError();
                String field = fieldError.getField();
                String defaultMessage = fieldError.getDefaultMessage();
                logger.error(ex.getMessage(),ex);
                return ResultVo.fail(defaultMessage);
            }else {
                logger.error(ex.getMessage(),ex);
                return new ResultVo(ResultCode.FAILURE);
            }
        }else {
            logger.error(ex.getMessage(),ex);
            return new ResultVo(ResultCode.FAILURE);
        }
    }

    /**
     * 处理其他异常
     * @param request
     * @param e
     * @return
     */
    @ExceptionHandler(value =Exception.class)
    @ResponseBody
    public ResultVo exceptionHandler(HttpServletRequest request, Exception e){
        logger.error("未知异常！原因是:",e);
        return ResultVo.fail(ResultCode.INTERNAL_SERVER_ERROR);
    }

    /**
     * Http请求消息序列化异常
     * @param e
     * @return
     */
    @ExceptionHandler({HttpMessageNotReadableException.class})
    @ResponseBody
    public ResultVo messageExceptionHandler(HttpMessageNotReadableException e) {
        log.warn("http请求参数转换异常: "+ e.getMessage());
        return ResultVo.fail(ResultCode.BODY_NOT_MATCH);
    }
   // MethodArgumentNotValidException


    /**
     * Http请求消息序列化异常
     * @param e
     * @return
     */
    @ExceptionHandler({JsonParseException.class})
    @ResponseBody
    public ResultVo JsonParseExceptionHandler(JsonParseException e) {
        log.warn("http请求参数转换异常: "+ e.getMessage());
        return ResultVo.fail(ResultCode.BODY_NOT_MATCH);
    }

}
